﻿using System;
using System.Drawing;
using System.Windows.Forms;

namespace Cepheus
{
    static class DwmThumbnailHelper
    {
        public static Size GetExactThumbnailSize(IntPtr sourceWindow)
        {
            Form tmpForm = new Form();
            IntPtr thumbnailHandle = DwmThumbnailHelper.CreateWindowThumbnail(tmpForm.Handle, sourceWindow, tmpForm.Bounds, 255);
            DwmAPI.PSIZE exactThumbnailSize = DwmThumbnailHelper.GetDwmThumbnailSize(thumbnailHandle);
            UnregisterThumbnail(thumbnailHandle);
            return new Size(exactThumbnailSize.x, exactThumbnailSize.y);
        }

        public static DwmAPI.PSIZE GetDwmThumbnailSize(IntPtr thumbnailHandle)
        {
            DwmAPI.PSIZE result = new DwmAPI.PSIZE();
            if (IsDwmCompositionEnabled() && thumbnailHandle != IntPtr.Zero)
            {
                try
                {
                    DwmAPI.DwmQueryThumbnailSourceSize(thumbnailHandle, out result);
                }
                catch { }
            }

            return result;
        }

        public static IntPtr CreateWindowThumbnail(IntPtr parentWindow, IntPtr sourceWindow, Rectangle bounds, byte opacity)
        {
            IntPtr thumbnail = IntPtr.Zero;

            if (DwmThumbnailHelper.IsDwmCompositionEnabled() && parentWindow != IntPtr.Zero && sourceWindow != IntPtr.Zero && Win32APIImports.IsWindow(sourceWindow) && Win32APIImports.IsWindow(parentWindow))
            {
                try
                {
                    int result = DwmAPI.DwmRegisterThumbnail(parentWindow, sourceWindow, out thumbnail);
                    if (result == 0)
                        UpdateWindowThumbnail(sourceWindow, thumbnail, bounds, opacity);
                }
                catch { }
            }

            return thumbnail;
        }

        public static void UpdateWindowThumbnail(IntPtr parentWindow, IntPtr thumbnail, Rectangle bounds, byte opacity)
        {
            if (DwmThumbnailHelper.IsDwmCompositionEnabled() && thumbnail != IntPtr.Zero && Win32APIImports.IsWindow(parentWindow))
            {
                try
                {
                    DwmAPI.DWM_THUMBNAIL_PROPERTIES thumbnailProperties = new DwmAPI.DWM_THUMBNAIL_PROPERTIES();
                    thumbnailProperties.dwFlags = DwmAPI.DWM_TNP_VISIBLE + DwmAPI.DWM_TNP_OPACITY + DwmAPI.DWM_TNP_RECTDESTINATION;
                    thumbnailProperties.opacity = opacity;
                    thumbnailProperties.fVisible = true;
                    thumbnailProperties.rcDestination = new Win32APIImports.RECT(bounds.Left, bounds.Top, bounds.Right, bounds.Bottom);

                    DwmAPI.DwmUpdateThumbnailProperties(thumbnail, ref thumbnailProperties);
                }
                catch { }
            }
        }

        public static void UpdateWindowThumbnail(IntPtr parentWindow, IntPtr thumbnail, byte opacity)
        {
            if (DwmThumbnailHelper.IsDwmCompositionEnabled() && thumbnail != IntPtr.Zero && Win32APIImports.IsWindow(parentWindow))
            {
                try
                {
                    DwmAPI.DWM_THUMBNAIL_PROPERTIES thumbnailProperties = new DwmAPI.DWM_THUMBNAIL_PROPERTIES();
                    thumbnailProperties.dwFlags = DwmAPI.DWM_TNP_VISIBLE + DwmAPI.DWM_TNP_OPACITY;
                    thumbnailProperties.opacity = opacity;
                    thumbnailProperties.fVisible = true;

                    DwmAPI.DwmUpdateThumbnailProperties(thumbnail, ref thumbnailProperties);
                }
                catch { }
            }
        }

        public static void UnregisterThumbnail(IntPtr thumbnail)
        {
            if (DwmThumbnailHelper.IsDwmCompositionEnabled() && thumbnail != IntPtr.Zero)
            {
                try
                {
                    DwmAPI.DwmUnregisterThumbnail(thumbnail);
                }
                catch { }
            }
        }

        public static bool IsDwmCompositionEnabled()
        {
            bool result = false;
            DwmAPI.DwmIsCompositionEnabled(ref result);
            return result;
        }
    }
}
